// 通用工具函数

/**
 * 格式化日期
 */
export const formatDate = (date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss') => {
  const d = new Date(date);
  if (isNaN(d.getTime())) return '';

  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  const hours = String(d.getHours()).padStart(2, '0');
  const minutes = String(d.getMinutes()).padStart(2, '0');
  const seconds = String(d.getSeconds()).padStart(2, '0');

  return format
    .replace('YYYY', String(year))
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds);
};

/**
 * 获取相对时间（多久前）
 */
export const getRelativeTime = (date: Date | string | number) => {
  const now = new Date().getTime();
  const target = new Date(date).getTime();
  const diff = now - target;

  if (diff < 60 * 1000) return '刚刚';
  if (diff < 60 * 60 * 1000) return `${Math.floor(diff / (60 * 1000))}分钟前`;
  if (diff < 24 * 60 * 60 * 1000) return `${Math.floor(diff / (60 * 60 * 1000))}小时前`;
  if (diff < 7 * 24 * 60 * 60 * 1000) return `${Math.floor(diff / (24 * 60 * 60 * 1000))}天前`;

  return formatDate(date, 'MM-DD');
};

/**
 * 防抖函数
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: number;

  return (...args: Parameters<T>) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait) as any;
  };
};

/**
 * 节流函数
 */
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  limit: number
): ((...args: Parameters<T>) => void) => {
  let inThrottle: boolean;

  return (...args: Parameters<T>) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
};

/**
 * 深拷贝
 */
export const deepClone = <T>(obj: T): T => {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj.getTime()) as any;
  if (obj instanceof Array) return obj.map(item => deepClone(item)) as any;
  if (typeof obj === 'object') {
    const clonedObj = {} as any;
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }
  return obj;
};

/**
 * 生成UUID
 */
export const generateUUID = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
};
// utils.js
/**
 * 获取用户文件目录（支持 App、小程序、H5）
 * 返回 Promise<string> —— 目录路径或虚拟路径
 */
export function getDbDir() {
  return new Promise((resolve, reject) => {
    // #ifdef APP-PLUS
    // ------- App 端 -------
    try {
      plus.io.requestFileSystem(plus.io.PRIVATE_DOC, fs => {
        if (fs.root) {
          fs.root.getDirectory(
            'user',
            { create: true },
            entry => resolve(entry.fullPath),
            err => reject(err)
          );
        } else {
          reject(new Error('fs.root is undefined'));
        }
      });
    } catch (e) {
      reject(e);
    }
    // #endif

    // #ifdef MP
    // ------- 小程序端 -------
    try {
      const fs = wx.getFileSystemManager();
      const userDir = `${wx.env.USER_DATA_PATH}/user`;
      fs.access({
        path: userDir,
        success: () => resolve(userDir),
        fail: () => {
          fs.mkdir({
            dirPath: userDir,
            recursive: true,
            success: () => resolve(userDir),
            fail: err => reject(err),
          });
        },
      });
    } catch (e) {
      reject(e);
    }
    // #endif

    // #ifdef H5
    // ------- H5 端 -------
    try {
      const userDirKey = 'userDirPath';
      let userDir = localStorage.getItem(userDirKey);
      if (!userDir) {
        userDir = 'virtual-user-dir-' + Date.now();
        localStorage.setItem(userDirKey, userDir);
      }
      resolve(userDir);
    } catch (e) {
      reject(e);
    }
    // #endif
  });
}

export const checkIsSafari = () =>
  /^((?!chrome|android).)*safari/i.test(navigator.userAgent) &&
  /iPad|iPhone|iPod/.test(navigator.userAgent);
